unit PerfilFunc2DM;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ZSqlUpdate, ZDataset, ZSequence, MainDM, DB, QueryConditions;

type

  { TPerfilFunc2Data }

  TPerfilFunc2Data = class(TMainDataModule)
    FuncDatasource: TDatasource;
    FuncZQuerydesc_funcionalidade: TStringField;
    FuncZQueryid_funcionalidade: TLargeintField;
    FuncZQuerymodulo: TStringField;
    ModuloDatasource: TDatasource;
    FuncZQuery: TZQuery;
    ModuloZQuery: TZQuery;
    ModuloZQuerydesc_acao: TStringField;
    ModuloZQuerydesc_funcionalidade: TStringField;
    ModuloZQueryid_funcionalidade: TLargeintField;
    ModuloZQueryid_funcionalidade_modulo: TLargeintField;
    ModuloZQuerymodulo: TStringField;
    PerfilFuncZQuerydesc_perfil: TStringField;
    PerfilFuncZQueryid_funcionalidades: TLargeintField;
    PerfilFuncZQueryid_perfil: TLargeintField;
    AuxiliarZQuery: TZQuery;
    ModuloZUpdate: TZUpdateSQL;
    PerfilZQuerydesc_perfil: TStringField;
    PerfilZQueryid_perfil: TLargeintField;
    AuxZQuery: TZQuery;
    procedure DataModuleCreate(Sender: TObject);
    /// Abre o DataSet
    procedure OpenDataSet(); override;
    /// Fecha o DataSet
    procedure CloseDataSet(); override;
    /// Realiza busca
    /// @param(Condicoes são as condições para a busca)
    /// @param(Tabela é a tabela no banco de dados)
    procedure Search(Condicoes: TQueryConditions; Tabela: string); override;
    procedure BuscaModuloPerfil(IDPerfil: string);
    procedure BuscaFuncionalidadePerfil(IDPerfil: string; Modulo: string);
    procedure LimpaFuncionalidades();
    procedure InsereModuloFuncionalidade(IDPerfil: string; Modulo: string);
    procedure RemoveModuloFuncionalidade(IDPerfil: string; Modulo: string);
    procedure InsereFuncionalidade(IDPerfil: string; Funcionalidade: string;Modulo:string);
    procedure RemoveFuncionalidade(IDPerfil: string; Funcionalidade: string;Modulo:string);
    procedure ModificaAcessoBotoes();

  private
    { private declarations }
  public
    { public declarations }
  end;

var
  PerfilFunc2Data: TPerfilFunc2Data;

implementation

uses ConnectionDM, UsuarioDM, MainFm;

{ TPerfilFunc2Data }

procedure TPerfilFunc2Data.DataModuleCreate(Sender: TObject);
begin
  MainDataSet := ModuloZQuery;
end;


procedure TPerfilFunc2Data.OpenDataSet();
begin
  ConnectionData.EmptyQuery(ModuloZQuery, 'funcionalidade');
  ModuloZQuery.Open;
end;

procedure TPerfilFunc2Data.CloseDataSet();
begin
  FuncZQuery.Close();
  ModuloZQuery.Close();
end;

procedure TPerfilFunc2Data.Search(Condicoes: TQueryConditions; Tabela: string);
begin
  ConnectionData.OpenQueryConditions(FuncZQuery, Tabela, Condicoes);
end;

procedure TPerfilFunc2Data.BuscaModuloPerfil(IDPerfil: string);
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('select f.desc_funcionalidade,(case when pf.id_funcionalidade is not null then');
    SQL.Add(':S else :N end)as acesso,(case when f.id_funcionalidade_modulo is null then');
    SQL.Add(':S else :N end)as modulo FROM funcionalidade as f left join perfil_funcionalidade as pf');
    SQL.Add('on pf.id_perfil=:id_perfil AND pf.id_funcionalidade=f.id_funcionalidade');
    ParamByName('id_perfil').AsString := IDPerfil;
    ParamByName('S').AsString := 'S';
    ParamByName('N').AsString := 'N';
    Open();
  end;
end;

procedure TPerfilFunc2Data.BuscaFuncionalidadePerfil(IDPerfil: string; Modulo: string);
var
  I, J: integer;
begin
  // Busca todas as funcionalidades do modulo especifico
  with FuncZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('select f.id_funcionalidade,f.desc_funcionalidade,');
    SQL.Add('(case when f.id_funcionalidade_modulo is not null then :S else :N end) as modulo');
    SQL.Add('FROM funcionalidade as f join');
    SQL.Add('funcionalidade as f2 on f2.id_funcionalidade=f.id_funcionalidade_modulo');
    SQL.Add('AND f.id_funcionalidade_modulo = (select id_funcionalidade FROM funcionalidade');
    SQL.Add('WHERE desc_funcionalidade =:modulo);');
    ParamByName('modulo').AsString := Modulo;
    Open();
  end;
  //Busca as funcionalidades do modulo e perfil especifico
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('select f.id_funcionalidade,f.desc_funcionalidade, ');
    SQL.Add('(case when pf.id_funcionalidade is not null then :S end) as acesso');
    SQL.Add('FROM funcionalidade as f join perfil_funcionalidade as pf ');
    SQL.Add('on pf.id_perfil=:id_perfil AND pf.id_funcionalidade=f.id_funcionalidade');
    SQL.Add('AND f.id_funcionalidade_modulo = ');
    SQL.Add('(select id_funcionalidade FROM funcionalidade where desc_funcionalidade =:modulo);');
    ParamByName('id_perfil').AsString := IDPerfil;
    ParamByName('modulo').AsString := Modulo;
    ParamByName('S').AsString := 'S';
    Open();
  end;

  for I := 1 to FuncZQuery.RecordCount do begin
    FuncZQuery.RecNo := I;
    FuncZQuery.Edit();
    FuncZQuery.FieldByName('modulo').AsString := 'N';
    FuncZQuery.Post;
    for J := 0 to AuxiliarZQuery.RecordCount do begin
      AuxiliarZQuery.RecNo := J;
      if FuncZQuery.FieldByName('id_funcionalidade').AsString =
        AuxiliarZQuery.FieldValues['id_funcionalidade'] then begin
        FuncZQuery.Edit();
        FuncZQuery.FieldByName('modulo').AsString := 'S';
        FuncZQuery.Post();
      end;
    end;
  end;
end;

procedure TPerfilFunc2Data.LimpaFuncionalidades();
begin
  with FuncZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * FROM funcionalidade limit 0');
    Open();
  end;
end;

procedure TPerfilFunc2Data.InsereModuloFuncionalidade(IDPerfil: string; Modulo: string);
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('INSERT into perfil_funcionalidade(id_perfil,id_funcionalidade) ');
    SQL.Add('SELECT :id_perfil, f2.id_funcionalidade FROM funcionalidade as f, funcionalidade as f2 ');
    SQL.Add('WHERE (f.id_funcionalidade = f2.id_funcionalidade_modulo or');
    SQL.Add('f2.desc_funcionalidade =:modulo) AND f.desc_funcionalidade =:modulo');
    ParamByName('id_perfil').AsString := IDPerfil;
    ParamByName('modulo').AsString := Modulo;
    ExecSQL();
  end;
end;

procedure TPerfilFunc2Data.RemoveModuloFuncionalidade(IDPerfil: string; Modulo: string);
var
  I: integer;
begin
  with AuxZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('select f2.id_funcionalidade FROM funcionalidade as f, funcionalidade as f2, ');
    SQL.Add('perfil_funcionalidade as pf');
    SQL.Add('WHERE (f.id_funcionalidade = f2.id_funcionalidade_modulo or');
    SQL.Add('f2.desc_funcionalidade =:modulo) AND f.desc_funcionalidade =:modulo');
    SQL.Add('AND f2.id_funcionalidade = pf.id_funcionalidade AND pf.id_perfil =:id_perfil');
    ParamByName('modulo').AsString := Modulo;
    ParamByName('id_perfil').AsString := IDPerfil;
    Open();
  end;
  for I := 0 to AuxZQuery.RecordCount do begin
    AuxZQuery.RecNo := I;
    with AuxiliarZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('Delete from perfil_funcionalidade WHERE id_perfil=:id_perfil');
      SQL.Add('AND id_funcionalidade =:id_funcionalidade');
      ParamByName('id_perfil').AsString := IDPerfil;
      ParamByName('id_funcionalidade').AsString :=
        AuxZQuery.FieldByName('id_funcionalidade').AsString;
      ExecSQL();
    end;
  end;
  LimpaFuncionalidades();
end;

procedure TPerfilFunc2Data.InsereFuncionalidade(IDPerfil: string;
  Funcionalidade: string; Modulo: string);
begin
   with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('INSERT into perfil_funcionalidade(id_perfil,id_funcionalidade)');
    SQL.Add('VALUES (:id_perfil,:id_funcionalidade)');
    ParamByName('id_perfil').AsString := IDPerfil;
    ParamByName('id_funcionalidade').AsString := Funcionalidade;
    ExecSQL();
  end;
   BuscaFuncionalidadePerfil(IDPerfil,Modulo);
end;

procedure TPerfilFunc2Data.RemoveFuncionalidade(IDPerfil: string;
  Funcionalidade: string; Modulo: string);
begin
   with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('DELETE FROM perfil_funcionalidade');
    SQL.Add('WHERE id_perfil=:id_perfil AND id_funcionalidade=:id_funcionalidade');
    ParamByName('id_perfil').AsString := IDPerfil;
    ParamByName('id_funcionalidade').AsString := Funcionalidade;
    ExecSQL();
  end;
   BuscaFuncionalidadePerfil(IDPerfil,Modulo);
end;

procedure TPerfilFunc2Data.ModificaAcessoBotoes();
begin
  UsuarioData.HabilitaAcoes(MainForm.Usuario);
end;


initialization
  {$I perfilfunc2dm.lrs}

end.
